
#include < stdio.h > 
#include < string.h > 
#include < stdlib.h > 

#define HASH_VALUE_MAX 1024



enum datatype
{
	INT, STRING, CHAR, DOUBLE
}; 

typedef struct hashtrunk
{
	char *databuf; 
	size_t datatype; 
	struct hashtrunk *next, *prev; 
}hashtrunk; 

hashtrunk *m_htrunk[1024] = {0}; 

int hash_init()
{
	for (int i = 0; i <  HASH_VALUE_MAX; i++) {
		m_htrunk[i] = (hashtrunk*)malloc(sizeof(hashtrunk)); 
		m_htrunk[i]->next = NULL; 
		m_htrunk[i]->prev = NULL; 
	}
	return 0; 
}

/*	kamailio hash function	*/
/** internal use: hash update
 * params: char* s   - string start, 
 *         char* end - end
 *         char* p,  and unsigned v temporary vars (used)
 *         unsigned h - result
 * h should be initialized (e.g. set it to 0), the result in h */
#define hash_update_str(s, end, p, v, h) \
	do { \
		for ((p) = (s); (p) <= ((end)-4); (p)+ = 4) { \
			(v) = (*(p) < < 24)+((p)[1] < < 16)+((p)[2] < < 8)+(p)[3]; \
			(h)+ = (v)^((v) > > 3); \
		} \
		switch((end)-(p)) {\
			case 3: \
				(v) = (*(p) < < 16)+((p)[1] < < 8)+(p)[2]; break; \
			case 2: \
				(v) = (*(p) < < 8)+p[1]; break; \
			case 1: \
				(v) = *p; break; \
			default: \
				(v) = 0; break; \
		} \
		(h)+ = (v)^((v) > > 3); \
	}while (0)

#define hash_finish(h) (((h)+((h) > > 11))+(((h) > > 13)+((h) > > 23)))

/*	linux hash function	*/

static size_t key_hash(const void *key)
{
	const char *str = (const char *)key; 
	size_t hash = 0; 

	while (*str ! = '\0') {
		hash * = 31; 
		hash + = *str; 
		str++; 
	}
	return hash; 
}


/*	stdc-lib hash function	*/
unsigned long int
stdc_hashfunc (const char *str_param) {
	  hval ^ = g > >  (32 - 8); 
	  hval ^ = g; 
	}
    }
  return hval; 
}

/*	apache hash function here	*/
static unsigned int apr_hashfunc(const char *char_key, size_t *klen, 
                                     unsigned int hash)
{
    const unsigned char *key = (const unsigned char *)char_key; 
    const unsigned char *p; 
    size_t i; 
   

    if (*klen == -1) {
        for (p = key; *p; p++) {
            hash = hash * 33 + *p; 
        }
        *klen = p - key; 
    }
    else {
        for (p = key, i = *klen; i; i--, p++) {
            hash = hash * 33 + *p; 
        }
    }

    return hash; 
}

/*	sqlite hash function	*/
static unsigned int sqlite_hashfunc(const char *z) {
  unsigned int h = 0; 
  unsigned char c; 
  while ( (c = (unsigned char)*z++)! = 0 ) {
    h + = c >= 0?c:c+255; 
    h * = 0x9e3779b1; 
  }
  return h; 
}

/*	stdc++ hash function	*/
 inline size_t	stdcplus_hashfuc(const char* __s)
{
	unsigned long __h = 0; 
	for ( ; *__s; ++__s)
		__h = 5 * __h + *__s; 
	return size_t(__h); 
}

size_t GetHashValue(const char *s, size_t slen, unsigned long ihash, const char *hfunctype)
{
	if (strcmp(hfunctype, "apr") == 0) {
		
	}
	else if (strcmp(hfunctype, "stdc++") == 0) {
		
	}
	else if (strcmp(hfunctype, "linux") == 0) {
		
	}
	else if (strcmp(hfunctype, "sqlite") == 0) {
		
	}
	else if (strcmp(hfunctype, "kamailio") == 0) {
		
	}
	else
	{
		
	}
}

size_t InsertHashTable(/*const char *key, */unsigned long hash, hashtrunk **m_ht)
{
	char databuf[100]; 
	hashtrunk *tmp = NULL; 
	memset(databuf, 0, sizeof(databuf)); 
	printf("input your data:"); 
	scanf("%s", databuf); 
	if (m_ht[hash % HASH_VALUE_MAX] && m_ht[hash % HASH_VALUE_MAX]->databuf ! = NULL) {
		tmp = (hashtrunk*)malloc(sizeof(hashtrunk)); 
		if (tmp == NULL)	return -1; 
		tmp->next = m_ht[hash%HASH_VALUE_MAX]; 
		m_ht[hash%HASH_VALUE_MAX]->prev = tmp; 
		m_ht[hash%HASH_VALUE_MAX] = tmp; 
		tmp->prev = NULL; 
	} else {
	
	}
	m_ht[hash%HASH_VALUE_MAX]->databuf = new char[sizeof(databuf)]; 
	memcpy(m_ht[hash%HASH_VALUE_MAX]->databuf, databuf, sizeof(databuf)); 
}

int main()
{
	char com_str[20]; 
	char databuf[100]; 
	size_t datalen; 

	hash_init(); 
	
	while (1) {
		printf("please input your hash function to test:\n"); 
		printf("now we have:\napr\nstdc\nlinux\nkamailio\nstdc++\nsqlite\n == == == == == == == == == == = \n"); 
		memset(com_str, 0, 20); 
		scanf("%s", com_str); 
		if (strcmp(com_str, "apr") == 0)
		{
			char apr_key[100]; 
			size_t apr_key_len; 
			unsigned int apr_hash = 0; 
			memset(apr_key, 0, 100); 
			do
			{
				printf("please input a key and hash, then we will get a hash value!\n"); 
				printf("key:"); 
				scanf("%s", apr_key); 
				printf("hash:"); 
				scanf("%d", &apr_hash); 
				apr_key_len = strlen(apr_key); 
				apr_hash = apr_hashfunc(apr_key, &apr_key_len, apr_hash); 
				printf("hash value is:%x\n", apr_hash); 
				
				InsertHashTable(apr_hash, m_htrunk); 
			}while (0); 
		}
		else if (strcmp(com_str, "stdc") == 0)
		{
			char stdc_key[100]; 
			unsigned int stdc_hash = 0; 
			memset(stdc_key, 0, 100); 
			do
			{
				printf("please input a key and hash, then we will get a hash value!\n"); 
				printf("key:"); 
				scanf("%s", stdc_key); 
				stdc_hash = stdc_hashfunc(stdc_key); 
				printf("hash value is:%x\n", stdc_hash); 
				
				InsertHashTable(stdc_hash, m_htrunk); 
			}while (0); 
		}
		else if (strcmp(com_str, "linux") == 0)
		{
			char linux_key[100]; 
			unsigned int linux_hash = 0; 
			memset(linux_key, 0, 100); 
			do
			{
				printf("please input a key and hash, then we will get a hash value!\n"); 
				printf("key:"); 
				scanf("%s", linux_key); 
				linux_hash = key_hash(linux_key); 
				printf("hash value is:%x\n", linux_hash); 
				
				InsertHashTable(linux_hash, m_htrunk); 
			}while (0); 
		}
		else if (strcmp(com_str, "kamailio") == 0)
		{
			char kamailio_key[100]; 
			memset(kamailio_key, 0, 100); 
			char *tptr; 
			unsigned int tmp; 
			char *end; 
			unsigned int kamailio_hash; 
			do
			{
				printf("please input a key and hash, then we will get a hash value!\n"); 
				printf("key:"); 
				scanf("%s", kamailio_key); 
				end = kamailio_key + strlen(kamailio_key); 
				hash_update_str(kamailio_key, end, tptr, tmp, kamailio_hash); 
				hash_finish(kamailio_hash); 
				printf("hash value is:%x\n", kamailio_hash); 
				
				InsertHashTable(kamailio_hash, m_htrunk); 
			}while (0); 
		}
		else if (strcmp(com_str, "exit") == 0)
		{
			break; 
		}
		else if (strcmp(com_str, "stdc++") == 0)
		{
			char stdcplus_key[100]; 
			unsigned int stdcplus_hash = 0; 
			memset(stdcplus_key, 0, 100); 
			do
			{
				printf("please input a key and hash, then we will get a hash value!\n"); 
				printf("key:"); 
				scanf("%s", stdcplus_key); 
				stdcplus_hash = stdc_hashfunc(stdcplus_key); 
				printf("hash value is:%x\n", stdcplus_hash); 
				
				InsertHashTable(stdcplus_hash, m_htrunk); 
			}while (0); 
		}
		else if (strcmp(com_str, "sqlite") == 0)
		{
			char sqlite_key[100]; 
			unsigned int sqlite_hash = 0; 
			memset(sqlite_key, 0, 100); 
			do
			{
				printf("please input a key and hash, then we will get a hash value!\n"); 
				printf("key:"); 
				scanf("%s", sqlite_key); 
				sqlite_hash = sqlite_hashfunc(sqlite_key); 
				printf("hash value is:%x\n", sqlite_hash); 
				
				InsertHashTable(sqlite_hash, m_htrunk); 
			}while (0); 
		}
	}
	for (int i = 0; i < 1024; i++) {
		printf("trunk[%d]:\t", i); 
		hashtrunk *tmp = m_htrunk[i]; 
		while (tmp ! = NULL) {
			if (tmp->databuf)
				printf("%s\t", tmp->databuf); 
			tmp = tmp->next; 
		}
		printf("\n"); 
	}
	printf("Bye!\n"); 
	
	return 0; 
}
m_htrunk); 
			}while (0); 
		}
	}
	for (int i = 0; i < 1024; i++) {
		printf("trunk[%d]:\t", i); 
		hashtrunk *tmp = m_htrunk[i]; 
		while (tmp ! = NULL) {
			if (tmp->databuf)
				printf("%s\t", tmp->databuf); 
			tmp = tmp->next; 
		}
		printf("\n"); 
	}
	printf("Bye!\n"); 
	
	return 0; 
}